{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### Content under Creative Commons Attribution license CC-BY 4.0, code under BSD 3-Clause License © 2017 L.A. Barba, N.C. Clementi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<link href=\"https://fonts.googleapis.com/css?family=Merriweather:300,300i,400,400i,700,700i,900,900i\" rel='stylesheet' >\n",
       "<link href=\"https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,400,400i,700,700i\" rel='stylesheet' >\n",
       "<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:300,400' rel='stylesheet' >\n",
       "<style>\n",
       "\n",
       "@font-face {\n",
       "    font-family: \"Computer Modern\";\n",
       "    src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');\n",
       "}\n",
       "\n",
       "\n",
       "#notebook_panel { /* main background */\n",
       "    background: rgb(245,245,245);\n",
       "}\n",
       "\n",
       "div.cell { /* set cell width */\n",
       "    width: 800px;\n",
       "}\n",
       "\n",
       "div #notebook { /* centre the content */\n",
       "    background: #fff; /* white background for content */\n",
       "    width: 1000px;\n",
       "    margin: auto;\n",
       "    padding-left: 0em;\n",
       "}\n",
       "\n",
       "#notebook li { /* More space between bullet points */\n",
       "margin-top:0.5em;\n",
       "}\n",
       "\n",
       "/* draw border around running cells */\n",
       "div.cell.border-box-sizing.code_cell.running { \n",
       "    border: 1px solid #111;\n",
       "}\n",
       "\n",
       "/* Put a solid color box around each cell and its output, visually linking them*/\n",
       "div.cell.code_cell {\n",
       "    background-color: rgb(256,256,256); \n",
       "    border-radius: 0px; \n",
       "    padding: 0.5em;\n",
       "    margin-left:1em;\n",
       "    margin-top: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "div.text_cell_render{\n",
       "    font-family: 'Source Sans Pro', sans-serif;\n",
       "    line-height: 140%;\n",
       "    font-size: 110%;\n",
       "    width:680px;\n",
       "    margin-left:auto;\n",
       "    margin-right:auto;\n",
       "}\n",
       "\n",
       "/* Formatting for header cells */\n",
       ".text_cell_render h1 {\n",
       "    font-family: 'Merriweather', serif;\n",
       "    font-style:regular;\n",
       "    font-weight: bold;    \n",
       "    font-size: 250%;\n",
       "    line-height: 100%;\n",
       "    color: #004065;\n",
       "    margin-bottom: 1em;\n",
       "    margin-top: 0.5em;\n",
       "    display: block;\n",
       "}\t\n",
       ".text_cell_render h2 {\n",
       "    font-family: 'Merriweather', serif;\n",
       "    font-weight: bold; \n",
       "    font-size: 180%;\n",
       "    line-height: 100%;\n",
       "    color: #0096d6;\n",
       "    margin-bottom: 0.5em;\n",
       "    margin-top: 0.5em;\n",
       "    display: block;\n",
       "}\t\n",
       "\n",
       ".text_cell_render h3 {\n",
       "    font-family: 'Merriweather', serif;\n",
       "\tfont-size: 150%;\n",
       "    margin-top:12px;\n",
       "    margin-bottom: 3px;\n",
       "    font-style: regular;\n",
       "    color: #008367;\n",
       "}\n",
       "\n",
       ".text_cell_render h4 {    /*Use this for captions*/\n",
       "    font-family: 'Merriweather', serif;\n",
       "    font-weight: 300; \n",
       "    font-size: 100%;\n",
       "    line-height: 120%;\n",
       "    text-align: left;\n",
       "    width:500px;\n",
       "    margin-top: 1em;\n",
       "    margin-bottom: 2em;\n",
       "    margin-left: 80pt;\n",
       "    font-style: regular;\n",
       "}\n",
       "\n",
       ".text_cell_render h5 {  /*Use this for small titles*/\n",
       "    font-family: 'Source Sans Pro', sans-serif;\n",
       "    font-weight: regular;\n",
       "    font-size: 130%;\n",
       "    color: #e31937;\n",
       "    font-style: italic;\n",
       "    margin-bottom: .5em;\n",
       "    margin-top: 1em;\n",
       "    display: block;\n",
       "}\n",
       "\n",
       ".text_cell_render h6 { /*use this for copyright note*/\n",
       "    font-family: 'Source Code Pro', sans-serif;\n",
       "    font-weight: 300;\n",
       "    font-size: 9pt;\n",
       "    line-height: 100%;\n",
       "    color: grey;\n",
       "    margin-bottom: 1px;\n",
       "    margin-top: 1px;\n",
       "}\n",
       "\n",
       "    .CodeMirror{\n",
       "            font-family: \"Source Code Pro\";\n",
       "\t\t\tfont-size: 90%;\n",
       "    }\n",
       "/*    .prompt{\n",
       "        display: None;\n",
       "    }*/\n",
       "\t\n",
       "    \n",
       "    .warning{\n",
       "        color: rgb( 240, 20, 20 )\n",
       "        }  \n",
       "</style>\n",
       "<script>\n",
       "    MathJax.Hub.Config({\n",
       "                        TeX: {\n",
       "                           extensions: [\"AMSmath.js\"], \n",
       "                           equationNumbers: { autoNumber: \"AMS\", useLabelIds: true}\n",
       "                           },\n",
       "                tex2jax: {\n",
       "                    inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
       "                    displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
       "                },\n",
       "                displayAlign: 'center', // Change this to 'center' to center equations.\n",
       "                \"HTML-CSS\": {\n",
       "                    styles: {'.MathJax_Display': {\"margin\": 4}}\n",
       "                }\n",
       "        });\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Execute this cell to load the notebook's style sheet, then ignore it\n",
    "from IPython.core.display import HTML\n",
    "css_file = '../style/custom.css'\n",
    "HTML(open(css_file, \"r\").read())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Play with data in Jupyter\n",
    "\n",
    "This is the second lesson of our course in _\"Engineering Computations.\"_ In the first lesson, [_Interacting with Python_](http://nbviewer.jupyter.org/github/engineersCode/EngComp/blob/8693986dbc0554495930c87bae7283bfa78130bd/modules/1_offtheground/1_Interacting_with_Python.ipynb), we used **IPython**, the interactive Python shell. It is really great to type single-line Python expressions and get the outputs, interactively. Yet, believe it or not, there are greater things! \n",
    "\n",
    "In this lesson, you will continue playing with data using Python, but you will do so in a **Jupyter notebook**. This very lesson is written in a Jupyter notebook. Ready? You will love it."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## What is Jupyter?\n",
    "\n",
    "Jupyter is a set of open-source tools for interactive and exploratory computing. You work right on your browser, which becomes the user interface through which Jupyter gives you a file explorer (the _dashboard_) and a document format: the **notebook**.\n",
    "\n",
    "A Jupyter notebook can contain: input and output of code, formatted text, images, videos, pretty math equations, and much more. The computer code is _executable_, which means that you can run the bits of code, right in the document, and get the output of that code displayed for you. This interactive way of computing, mixed with the multi-media narrative, allows you to tell a story (even to yourself) with extra powers!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Working in Jupyter\n",
    "\n",
    "Several things will seem counter-intuitive to you at first. For example, most people are used to launching apps in their computers by clicking some icon: this is the first thing to \"unlearn.\" Jupyter is launched from the _command line_ (like when you launched IPython). Next, we have two types of content—code and markdown—that handle a bit differently. The fact that your browser is an interface to a compute engine (called \"kernel\") leads to some extra housekeeping (like shutting down the kernel). But you'll get used to it pretty quick!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Start Jupyter\n",
    "\n",
    "The standard way to start Jupyter is to type the following in the command-line interface:\n",
    "\n",
    "`jupyter notebook` \n",
    "\n",
    "Hit enter and tadah!!\n",
    "After a little set up time, your default browser will open with the Jupyter app. It should look like in the screenshot below, but you may see a list of files and folders, depending on the location of your computer where you launched it.\n",
    "\n",
    "##### Note:\n",
    "\n",
    "Don't close the terminal window where you launched Jupyter (while you're still working on Jupyter). If you need to do other tasks on the command line, open a new terminal window.\n",
    "\n",
    "<img src=\"images/jupyter-main.png\" style=\"width: 800px;\"/> \n",
    "#### Screenshot of the Jupyter dashboard, open in the browser.\n",
    "\n",
    "\n",
    "To start a new Jupyter notebook, click on the top-right, where it says **New**, and select `Python 3`. Check out the screenshot below.\n",
    "\n",
    "<img src=\"images/create_notebook.png\" style=\"width: 800px;\"/> \n",
    "#### Screenshot showing how to create a new notebook.\n",
    "\n",
    "A new tab will appear in your browser and you will see an empty notebook, with a single input line, waiting for you to enter some code. See the next screenshot.\n",
    "\n",
    "<img src=\"images/new_notebook.png\" style=\"width: 800px;\"/> \n",
    "#### Screenshot showing an empty new notebook.\n",
    "\n",
    "The notebook opens by default with a single empty code cell. Try to write some Python code there and execute it by hitting `[shift] + [enter]`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Notebook cells\n",
    "\n",
    "The Jupyter notebook uses _cells_: blocks that divide chunks of text and code. Any text content is entered in a *Markdown* cell: it contains text that you can format using simple markers to get headings, bold, italic, bullet points, hyperlinks, and more.\n",
    "\n",
    "Markdown is easy to learn, check out the syntax in the [\"Daring Fireball\"](https://daringfireball.net/projects/markdown/syntax) webpage (by John Gruber). A few tips:\n",
    "\n",
    "* to create a title, use a hash to start the line: `# Title`\n",
    "* to create the next heading, use two hashes (and so on): `## Heading`\n",
    "* to italicize a word or phrase, enclose it in asterisks (or underdashes): `*italic*` or `_italic_`\n",
    "* to make it bold, enclose it with two asterisks: `**bolded**`\n",
    "* to make a hyperlink, use square and round brackets: `[hyperlinked text](url)`\n",
    "\n",
    "Computable content is entered in code cells. We will be using the IPython kernel (\"kernel\" is the name used for the computing engine), but you should know that Jupyter can be used with many different computing languages. It's amazing.\n",
    "\n",
    "A code cell will show you an input mark, like this: \n",
    "\n",
    "`In [ ]:`\n",
    "\n",
    "Once you add some code and execute it, Jupyter will add a number ID to the input cell, and produce an output marked like this:\n",
    "\n",
    "`Out [1]:`\n",
    "\n",
    "##### A bit of history: \n",
    "\n",
    "Markdown was co-created by the legendary but tragic [Aaron Swartz](https://en.wikipedia.org/wiki/Aaron_Swartz). The biographical documentary about him is called [\"The Internet's Own Boy,\"](https://en.wikipedia.org/wiki/The_Internet%27s_Own_Boy) and you can view it in YouTube or Netflix. Recommended!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Interactive computing in the notebook\n",
    "\n",
    "Look at the icons on the menu of Jupyter (see the screenshots above). The first icon on the left (an old floppy disk) is for saving your notebook. You can add a new cell with the big **+** button. Then you have the cut, copy, and paste buttons. The arrows are to move your current cell up or down. Then you have a button to \"run\" a code cell (execute the code), the square icon means \"stop\" and the swirly arrow is to \"restart\" your notebook's kernel (if the computation is stuck, for example). Next to that, you have the cell-type selector: Code or Markdown (or others that you can ignore for now).\n",
    "\n",
    "You can test-drive a code cell by writing some arithmetic operations. Like we saw in our first lesson, the Python operators are:\n",
    "```python\n",
    "    +   -   *   /   **   %   //\n",
    "```\n",
    "\n",
    "There's addition, subtraction, multiplication and division. The last three operators are _exponent_ (raise to the power of), _modulo_ (divide and return remainder) and _floor division_.\n",
    "\n",
    "Typing `[shift] + [enter]` will execute the cell and give you the output in a new line, labeled `Out[1]` (the numbering increases each time you execute a cell).\n",
    "\n",
    "##### Try it!\n",
    "\n",
    "Add a cell with the plus button, enter some operations, and `[shift] + [enter]` to execute."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Everything we did using IPython we can do in code cells within a Jupyter notebook. Try out some of the things we learned in lesson 1: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World!\n"
     ]
    }
   ],
   "source": [
    "print(\"Hello World!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = 2**8\n",
    "x < 64"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Edit mode and Command mode\n",
    "\n",
    "Once you click on a notebook cell to select it, you may interact with it in two ways, which are called _modes_. Later on, when you are reviewing this material again, read more about this in Reference 1. \n",
    "\n",
    "**Edit mode:**\n",
    "\n",
    "* We enter **edit mode** by pressing `Enter` or double-clicking on the cell.\n",
    "\n",
    "* We know we are in this mode when we see a green cell border and a prompt in the cell area.\n",
    "\n",
    "* When we are in edit mode, we can type into the cell, like a normal text editor.\n",
    "\n",
    "\n",
    "**Command mode:**\n",
    "\n",
    "* We enter in **command mode** by pressing `Esc` or clicking outside the cell area.\n",
    "\n",
    "* We know we are in this mode when we see a grey cell border with a left blue margin.\n",
    "\n",
    "* In this mode, certain keys are mapped to shortcuts to help with\n",
    "  common actions.\n",
    "\n",
    "\n",
    "You can find a list of the shortcuts by selecting `Help->Keyboard Shortcuts`\n",
    "from the notebook menu bar. You may want to leave this for later, and come back to it, but it becomes more helpful the more you use Jupyter."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### How to shut down the kernel and exit\n",
    "\n",
    "Closing the browser tab where you've been working on a notebook does not immediately \"shut down\" the compute kernel. So you sometimes need to do a little housekeeping.\n",
    "\n",
    "Once you close a notebook, you will see in the main Jupyter app that your \n",
    "notebook file has a green book symbol next to it. You should click in the box at the left of that symbol, and then click where it says **Shutdown**. You don't need to do this all the time, but if you have a _lot_ of notebooks running, they will use resources in your machine.\n",
    "\n",
    "Similarly, Jupyter is still running even after you close the tab that has the Jupyter dashboard open. To exit the Jupyter app, you should go to the terminal that you used to open Jupyter, and type `[Ctrl] + [c]` to exit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Nbviewer\n",
    "\n",
    "[Nbviewer](http://nbviewer.jupyter.org/) is a free web service that allows you to share static versions of hosted notebook files, as if they were a web page. If a notebook file is publicly available on the web, you can view it by entering its URL in the nbviewer web page, and hitting the **Go!** button. The notebook will be rendered as a static page: visitors can read everything, but they cannot interact with the code. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Play with Python strings\n",
    "\n",
    "Let's keep playing around with strings, but now coding in a Jupyter notebook (instead of IPython). We recommend that you open a clean new notebook to follow along the examples in this lesson, typing the commands that you see. (If you copy and paste, you will save time, but you will learn little. Type it all out!)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "str_1 = 'hello'\n",
    "str_2 = 'world'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remember that we can concatenate strings (\"add\"), for example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "helloworld\n"
     ]
    }
   ],
   "source": [
    "new_string = str_1 + str_2\n",
    "print(new_string)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What if we want to add a space that separates `hello` from `world`? We directly add the string `' '` in the middle of the two variables. A space is a character!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "my_string = str_1 + ' ' + str_2\n",
    "print(my_string)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercise:\n",
    "\n",
    "Create a new string variable that adds three exclamation marks to the end of `my_string`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Indexing\n",
    "\n",
    "We can access each separate character in a string (or a continuous segment of it) using _indices_: integers denoting the position of the character in the string. Indices go in square brackets, touching the string variable name on the right. For example, to access the 1st element of `new_string`, we would enter `new_string[0]`. Yes! in Python we start counting from 0. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'h'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'l'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#If we want the 3rd element we do:\n",
    "my_string[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You might have noticed that in the cell above we have a line before the code that starts with the `#` sign. That line seems to be ignored by Python: do you know why?\n",
    "\n",
    "It is a _comment_: whenever you want to comment your Python code, you put a `#` in front of the comment. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'e'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[1] #this is how we access the second element of a string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How do we know the index of the last element in the string? \n",
    "\n",
    "Python has a built-in function called `len()` that gives the information about length of an object. Let's try it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(my_string)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Great! Now we know that `my_string` is eleven characters long. What happens if we enter this number as an index?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "ename": "IndexError",
     "evalue": "string index out of range",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-11-396b20cf330d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmy_string\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m11\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mIndexError\u001b[0m: string index out of range"
     ]
    }
   ],
   "source": [
    "my_string[11]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Oops. We have an error: why? We know that the length of `my_string` is eleven. But the integer 11 doesn't work as an index. If you expected to get the last element, it's because you forgot that Python starts counting at zero. Don't worry: it takes some getting used to.\n",
    "\n",
    "The error message says that the index is out of range: this is because the index of the _last element_ will always be: ` len(string) - 1`. In our case, that number is 10. Let's try it out."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'d'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[10]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python also offers a clever way to grab the last element so we don't need to calculate the lenghth and substract one: it is using a negative 1 for the index. Like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'d'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What if we use a `-2` as index?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'l'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[-2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That is the last `l` in the string ` hello world`. Python is so clever, it can count backwards!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Slicing strings\n",
    "\n",
    "Sometimes, we want to grab more than one single element: we may want a section of the string. We do it using _slicing_ notation in the square brackets. For example, we can use  `[start:end]`, where `start` is the index to begin the slice, and `end` is the (non-inclusive) index to finish the slice.  For example, to grab the word `hello` from our string, we do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hello'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[0:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can skip the `start` index, if you want to slice from the beginning of the string, and you can skip the `end` of a slice, indicating you want to go all the way to the end of the string. For example, if we want to grab the word `'world'` from `my_string`, we could do the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'world'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_string[6:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A helpful way to visualize slices is to imagine that the indices point to the spaces _between_ characters in the string. That way, when you write `my_string[i]`, you would be referring to the \"character to the right of `i`\" (Reference 2). \n",
    "\n",
    "Check out the diagram below. We start counting at zero; the letter `'g'` is to the right of index 2. So if we want to grab the sub-string `'gin'` from `'engineer'`, we need `[start:end]=[2:5]`.\n",
    "\n",
    "<img src=\"images/slicing.png\" style=\"width: 400px;\"/> \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Try it yourself!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'gin'"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Define your string\n",
    "eng_string = 'engineer'\n",
    "\n",
    "# Grab 'gin'slice\n",
    "eng_string[2:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercises: \n",
    "\n",
    "1. Define a string called `'banana'` and print out the first and last `'a'`. \n",
    "2. Using the same string, grab the 2 possible slices that correspond to the word `'ana'` and print them out.\n",
    "3. Create your own slicing exercise and ask your classmates to give it a try (work in groups of 3)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following lines contain the solutions; to reveal the answer, select the lines with the mouse:\n",
    " \n",
    "Solution Exercise 1:\n",
    "\n",
    "<span style=\"color:white\"> b = 'banana' </span>\n",
    "<span style=\"color:white\"> print(b[1]) </span>\n",
    "<span style=\"color:white\"> print(b[-1]) </span>\n",
    "\n",
    "\n",
    "Solution Exercise 2:\n",
    "\n",
    "<span style=\"color:white\"> print(b[1:4]) </span>\n",
    "<span style=\"color:white\"> print(b[3:]) </span>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### What else we can do with strings?\n",
    "\n",
    "Python has many useful built-in functions for strings. You'll learn a few of them in this section. A technical detail: in Python, some functions are associated with a particular class of objects (e.g., strings). The word **method** is used in this case, and we have a new way to call them: the dot operator. It is a bit counter-intuitive in that the name of the method comes _after the dot_, while the name of the particular object it acts on comes first. Like this: `mystring.method()`.\n",
    "\n",
    "If you are curious about the many available methods for strings, go to the section \"Built-in String Methods\" in this [tutorial](https://www.tutorialspoint.com/python3/python_strings.htm). \n",
    "\n",
    "Let's use a quote by Albert Einstein as a string and apply some useful string methods. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "AE_quote = \"Everybody is a genius. But if you judge a fish by its ability to climb a tree, it will live its whole life believing that it is stupid.\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The **`count()`** method gives the number of ocurrences of a substring in a range. The arguments for the range are optional. \n",
    "\n",
    "*Syntax:*\n",
    "\n",
    "`str.count(substring, start, end)`\n",
    "\n",
    "Here, `start` and `end` are integers that indicate the indices where to start and end the count. For example, if we want to know how many letters `'e'` we have in the whole string, we can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote.count('e')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we want to know how many of those `'e'` charachters are in the range `[0:20]`, we do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote.count('e', 0, 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can look for more complex strings, for example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote.count('Everybody')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The **find()** method tells us if a string `'substr'` occurs in the string we are applying the method on. The arguments for the range are optional.\n",
    "\n",
    "*Syntax:*\n",
    "\n",
    "`str.find(substr, start, end)`\n",
    "\n",
    "Where `start` and `end` are indices indicating where to start and end the slice to apply the `find()` method on.\n",
    "\n",
    "If the string `'substr'`is in the original string, the `find()` method will return the index where the substring starts, otherwise it will return `-1`.\n",
    "\n",
    "For example, let's find the word \"fish\" in the Albert Einstein quote."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote.find('fish')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we know the length of our sub-string, we can now apply slice notation to grab the word \"fish\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len('fish')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'fish'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote[42: 42 + len('fish')]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's see what happens when we try to look for a string that is not in the quote. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-1"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote.find('albert')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It returns `-1`… but careful, that doesn't mean that the position is at the end of the original string! If we read the [documentation](https://docs.python.org/3/library/stdtypes.html#string-methods), we confirm that a returned value of `-1` indicates that the sub-string we are looking for is _not in the string_ we are searching in. \n",
    "\n",
    "A similar method is **`index()`**: it works like the `find()` method, but throws an error if the string we are searching for is not found. \n",
    "\n",
    "*Syntax:*\n",
    "\n",
    "`str.index(substr, start, end)`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote.index('fish')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "substring not found",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-27-045c3b2defa4>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mAE_quote\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'albert'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m: substring not found"
     ]
    }
   ],
   "source": [
    "AE_quote.index('albert')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the example above, we used the `len()` function to calculate the length of the string `'fish'`, and we used the result to calculate the ending index. However, if the string is too long, having a line that calculates the length might be inconvenient or may make your code look messy. To avoid this, we can use the `find()` or `index()` methods to calculate the end position. In the `'fish'` example, we could look for the index of the word `'by'` (the word that follows `'fish'`) and subtract 1 from that index to get the index that corresponds to the space right after `'fish'`. There are many ways to slice strings, only limited by your imagination!\n",
    "\n",
    "##### Note:\n",
    "Remember that the ending index is not inclusive, which is why we want the index of the space that follows the string `'fish'`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "idx_start = AE_quote.index('fish')\n",
    "idx_end = AE_quote.index('by') - 1 # -1 to get the index off the space after 'fish'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'fish'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "AE_quote[idx_start:idx_end]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercises: \n",
    "\n",
    "1. Use the `count()` method to count how many letters `'a'` are in `AE_quote`?\n",
    "2. Using the same method, how many isolated letters `'a'` are in `AE_quote`?\n",
    "3. Use the `index()` method to find the position of the words  `'genius'`, `'judge'` and `'tree'` in `AE_quote`. \n",
    "4. Using slice syntax, extract the words in exercise 3 from `AE_quote`. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Two more string methods turn out to be useful when you are working with texts and you need to clean, separate or categorize parts of the text. \n",
    "\n",
    "Let's work with a different string, a quote by Eleanor Roosevelt:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "ER_quote = \"   Great minds discuss ideas; average minds discuss events; small minds discuss people.  \""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that the string we defined above contains extra white spaces at the beginning and at the end. In this case, we did it on purpose, but bothersome extra spaces are often present when reading text from a file (perhaps due to paragraph indentation). \n",
    "\n",
    "Strings have a method that allows us to get rid of those extra white spaces. \n",
    "\n",
    "The **`strip()`** method returns a copy of the string in which all characters given as argument are stripped from the beginning and the end of the string. \n",
    "\n",
    "*Syntax:*\n",
    "\n",
    "`str.strip([chars])`\n",
    "\n",
    "The default argument is the space character. For example, if we want to remove the white spaces in the `ER_quote`, and save the result back in `ER_quote`, we can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "ER_quote = ER_quote.strip()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Great minds discuss ideas; average minds discuss events; small minds discuss people.'"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ER_quote"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's supose you want to strip the period at the end; you could do the following:\n",
    "\n",
    "`ER_quote = ER_quote.strip('.')`\n",
    "\n",
    "But if we don't want to keep the changes in our string variable, we don't overwrite the variable as we did above. Let's just see how it looks:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Great minds discuss ideas; average minds discuss events; small minds discuss people'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ER_quote.strip('.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the string variable to confirm that it didn't change (it still has the period at the end):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Great minds discuss ideas; average minds discuss events; small minds discuss people.'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ER_quote"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another useful method is **`startswith()`**, to find out if a string starts with a certain character. \n",
    "Later on in this lesson we'll see a more interesting example; but for now, let's just \"check\" if our string starts with the word 'great'."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ER_quote.startswith('great')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The output is `False` because the word is not capitalized! Upper-case and lower-case letters are distinct characters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ER_quote.startswith('Great')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's important to mention that we don't need to match the character until we hit the white space. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ER_quote.startswith('Gre')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The last string method we'll mention is **`split()`**: it returns a **list** of all the words in a string. We can also define a separator and split our string according to that separator, and optionally we can limit the number of splits to `num`. \n",
    "\n",
    "*Syntax:*\n",
    "\n",
    "`str.split(separator, num)`\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Everybody', 'is', 'a', 'genius.', 'But', 'if', 'you', 'judge', 'a', 'fish', 'by', 'its', 'ability', 'to', 'climb', 'a', 'tree,', 'it', 'will', 'live', 'its', 'whole', 'life', 'believing', 'that', 'it', 'is', 'stupid.']\n"
     ]
    }
   ],
   "source": [
    "print(AE_quote.split())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Great', 'minds', 'discuss', 'ideas;', 'average', 'minds', 'discuss', 'events;', 'small', 'minds', 'discuss', 'people.']\n"
     ]
    }
   ],
   "source": [
    "print(ER_quote.split())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's split the `ER_quote` by a different character, a semicolon:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Great minds discuss ideas', ' average minds discuss events', ' small minds discuss people.']\n"
     ]
    }
   ],
   "source": [
    " print(ER_quote.split(';'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Think...\n",
    "\n",
    "Do you notice something new in the output of the `print()` calls above? \n",
    "What are those `[ ]`? \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Play with Python lists \n",
    "\n",
    "The square brackets above indicate a Python **list**. A list is a built-in data type consisting of a sequence of values, e.g., numbers, or strings. Lists work in many ways similarly to strings: their elements are numbered from zero, the number of elements is given by the function `len()`, they can be manipulated with slicing notation, and so on.\n",
    "\n",
    "The easiest way to create a list is to enclose a comma-separated sequence of values in square brackets: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 4, 7, 9]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# A list of integers \n",
    "[1, 4, 7, 9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['apple', 'banana', 'orange']"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# A list of strings\n",
    "['apple', 'banana', 'orange']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 'apple', 4.5, [5, 10]]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# A list with different element types\n",
    "[2, 'apple', 4.5, [5, 10]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the last list example, the last element of the list is actually _another list_. Yes! we can totally do that.\n",
    "\n",
    "We can also assign lists to variable names, for example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "integers = [1, 2, 3, 4, 5]\n",
    "fruits = ['apple', 'banana', 'orange']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "print(integers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['apple', 'banana', 'orange']\n"
     ]
    }
   ],
   "source": [
    "print(fruits)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_list = [integers, fruits]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1, 2, 3, 4, 5], ['apple', 'banana', 'orange']]\n"
     ]
    }
   ],
   "source": [
    "print(new_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that this `new_list` has only 2 elements. We can check that with the `len()` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(new_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each element of `new_list` is, of course, another list.\n",
    "As with strings, we access list elements with indices and slicing notation. The first element of `new_list` is the list of integers from 1 to 5, while the second element is the list of three fruit names. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, 5]"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_list[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['apple', 'banana', 'orange']"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_list[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['apple', 'banana']"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Accessing the first two elements of the list fruits\n",
    "fruits[0:2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercises:\n",
    "\n",
    "1. From the `integers` list, grab the slice `[2, 3, 4]` and then `[4, 5]`.\n",
    "2. Create your own list and design an exercise for grabbing slices, working with your classmates."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding elements to a list\n",
    "\n",
    "We can add elements to a list using the **append()** method: it appends the object we pass into the existing list. For example, to add the element 6 to our `integers` list, we can do: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "integers.append(6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's check that the `integer` list now has a 6 at the end: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6]\n"
     ]
    }
   ],
   "source": [
    "print(integers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List membership\n",
    "\n",
    "Checking for list membership in Python looks pretty close to plain English!\n",
    "\n",
    "*Syntax*\n",
    "\n",
    "To check if an element is **in** a list:\n",
    "\n",
    "`element in list`\n",
    "\n",
    "To check if an element is **not in** a list:\n",
    "\n",
    "`element not in list`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'strawberry' in fruits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'strawberry' not in fruits"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercises\n",
    "\n",
    "1. Add two different fruits to the `fruits` list. \n",
    "2. Check if `'mango'` is in your new `fruits` list. \n",
    "3. Given the list `alist = [1, 2, 3, '4', [5, 'six'], [7]]` run the following in separate cells and discuss the output with your classmates:\n",
    "\n",
    "```Python\n",
    "   4 in alist\n",
    "   5 in alist\n",
    "   7 in alist \n",
    "   [7] in alist\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Modifying elements of a list\n",
    "\n",
    "We can not only add elements to a list, we can also modify a specific element.\n",
    "Let's re-use the list from the exercise above, and replace some elements. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "alist = [1, 2, 3, '4', [5, 'six'], [7]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can find the position of a certain element with the `index()` method, just like with strings. For example, if we want to know where the element `'4'` is, we can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alist.index('4')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'4'"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alist[3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's replace it with the integer value `4`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "alist[3] = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 2, 3, 4, [5, 'six'], [7]]"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4 in alist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercise\n",
    "\n",
    "Replace the last element of `alist` with something different. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Being able to modify elements in a list is a \"property\"  of Python lists; other Python objects we'll see later in the course also behave like this, but not all Python objects do. For example, you cannot modify elements in a a string. If we try, Python will complain. \n",
    "\n",
    "Fine! Let's try it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "string = 'This is a string.'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Suppose we want to replace the period ('.') by an exaclamation mark ('!'). Can we just modify this string element?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'.'"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string[-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'str' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-65-5ef39e3cc98e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mstring\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'!'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "string[-1] = '!'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Told you! Python is confirming that we cannot change the elements of a string by item assignment. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next: strings and lists in action\n",
    "\n",
    "You have learned many things about strings and lists in this lesson, and you are probably eager to see how to apply it all to a realistic situation. We created a [full example](http://nbviewer.jupyter.org/github/engineersCode/EngComp/blob/master/modules/1_offtheground/3_Example_play_with_MAEbulletin.ipynb) in a separate notebook to show you the power of Python with text data.\n",
    "\n",
    "But before jumping in, we should introduce you to the powerful ideas of **iteration** and **conditionals** in Python. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Iteration with `for` statements\n",
    "\n",
    "The idea of _iteration_ (in plain English) is to repeat a process several times. If you have any programming experience with another language (like C or Java, say), you may have an idea of how to create iteration with `for` statements. But these are a little different in Python, as you can read in the [documentation](https://docs.python.org/3/tutorial/controlflow.html#for-statements).\n",
    "\n",
    "A Python `for` statement iterates over the items of a sequence, naturally. Say you have a list called `fruits` containing a sequence of strings with fruit names; you can write a statement like\n",
    "\n",
    "```Python\n",
    "for fruit in fruits:\n",
    "```\n",
    "to do something with each item in the list. \n",
    "\n",
    "Here, for the first time, we will encounter a distinctive feature of the Python language: grouping by **indentation**. To delimit _what_ Python should do with each `fruit` in the list of `fruits`, we place the next statement(s) _indented_ from the left. \n",
    "\n",
    "How much to indent? This is a style question, and everyone has a preference: two spaces, four spaces, one tab… they are all valid: but pick one and be consistent!\n",
    "\n",
    "Let's use four spaces:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eat your apple\n",
      "Eat your banana\n",
      "Eat your orange\n",
      "Eat your cherry\n",
      "Eat your mandarin\n"
     ]
    }
   ],
   "source": [
    "fruits = ['apple', 'banana', 'orange', 'cherry', 'mandarin']\n",
    "\n",
    "for fruit in fruits:\n",
    "    print(\"Eat your\", fruit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Pay attention:\n",
    "\n",
    "* the `for` statement ends with a colon, `:`\n",
    "* the variable `fruit` is implicitly defined in the `for` statement\n",
    "* `fruit` takes the (string) value of each element of the list `fruits`, in order\n",
    "* the indented `print()` statement is executed for each value of `fruit`\n",
    "* once Python runs out of `fruits`, it stops\n",
    "* we don't need to know ahead of time how many items are in the list!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Challenge question:\n",
    "\n",
    "— What is the value of the variable `fruit` after executing the `for` statement above? Discuss with your neighbor. (Confirm your guess in a code cell.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A very useful function to use with `for` statements is **`enumerate()`**: it adds a counter that you can use as an index while your iteration runs. To use it, you implicitly define _two_ variables in the `for` statement: the counter, and the value of the sequence being iterated on. \n",
    "\n",
    "Study the following block of code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Sam', 'Zoe', 'Naty', 'Gil', 'Tom']\n"
     ]
    }
   ],
   "source": [
    "names = ['sam', 'zoe', 'naty', 'gil', 'tom']\n",
    "\n",
    "for i, name in enumerate(names):\n",
    "    names[i] = name.capitalize()\n",
    "print(names)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Challenge question:\n",
    "\n",
    "— What is the value of the variable `name` after executing the `for` statement above? Discuss with your neighbor. (Confirm your guess in a code cell.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercise:\n",
    "\n",
    "Say we have a list of lists (a.k.a., a _nested_ list), as follows: \n",
    "```Python\n",
    "fullnames = [['sam','jones'], ['zoe','smith'],['joe','cheek'],['tom','perez'] ]\n",
    "```\n",
    "Write some code that creates two simple lists: one with the first names, another with the last names from the nested list above, but capitalized.\n",
    "\n",
    "To start, you need to create two _empty_ lists using the square brackets with nothing inside. We've done that for you below. _Hint_: Use the `append()` list method!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "fullnames = [ ['sam','jones'], ['zoe','smith'],['joe','cheek'],['tom','perez'] ]\n",
    "firstnames = []\n",
    "lastnames = []\n",
    "\n",
    "# Write your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Conditionals with `if` statements\n",
    "\n",
    "Sometimes we need the ability to check for conditions, and change the behavior of our program depending on the condition. We accomplish it with an `if` statement, which can take one of three forms."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(1) **If** statement on its own:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a is bigger than b\n"
     ]
    }
   ],
   "source": [
    "a = 8 \n",
    "b = 3\n",
    "\n",
    "if a > b:\n",
    "    print('a is bigger than b')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(2) **If-else** statement: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We pick a number, but you can change it\n",
    "x = 1547"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your number is a multiple of 17.\n"
     ]
    }
   ],
   "source": [
    "if x % 17 == 0: \n",
    "    print('Your number is a multiple of 17.')\n",
    "else:\n",
    "    print('Your number is not a multiple of 17.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Note:* The `%` represents a modulo operation: it gives the remainder from division of the first argument by the second"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Tip:* You can uncomment this following cell, and learn a good trick to ask the user to insert a number. You can use this instead of assigning a specific value to `x` above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#x = float(input('Insert your number: '))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(3) **If-elif-else** statement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a is smaller than b\n"
     ]
    }
   ],
   "source": [
    "a = 3\n",
    "b = 5\n",
    "\n",
    "if a > b:\n",
    "    print('a is bigger than b')\n",
    "elif a < b:\n",
    "    print('a is smaller than b')\n",
    "else:\n",
    "    print('a is equal to b')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Note:* We can have as many `elif` lines as we want."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Exercise\n",
    "\n",
    "Using `if`, `elif` and `else` statements write a code where you pick a 4-digit number, if it is divisible by 2 and 3 you print: 'Your number is not only divisible by 2 and 3 but also by 6'. If it is divisible by 2 you print: 'Your number is divisible by 2'. If it is divisible by 3 you print: 'Your number is divisible by 3'. Any other option, you print: 'Your number is not divisible by 2, 3 or 6'   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## What we've learned\n",
    "\n",
    "* How to use the Jupyter environnment.\n",
    "* Playing with strings: accessing values, slicing and string methods.\n",
    "* Playing with lists: accessing values, slicing and list methods.\n",
    "* Iteration with `for` statements.\n",
    "* Conditionals with `if` statements."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## References\n",
    "\n",
    "1. [Notebook Basics: Modal Editor](http://jupyter-notebook.readthedocs.io/en/latest/examples/Notebook/Notebook%20Basics.html)\n",
    "2. [\"Indices point between elements,\"](https://blog.nelhage.com/2015/08/indices-point-between-elements/) blog post by Nelson Elhage (2015).\n",
    "3. _Python for Everybody: Exploring Data Using Python 3_ (2016). Charles R. Severance. [PDF available](http://do1.dr-chuck.com/pythonlearn/EN_us/pythonlearn.pdf)\n",
    "4. _Think Python: How to Think Like a Computer Scientist_ (2012). Allen Downey. Green Tea Press.  [PDF available](http://greenteapress.com/thinkpython/thinkpython.pdf)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
